using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace ChEngine
{
   
    public partial class BitBoardDriver
    {
        public IBitBoard Board { get; private set; }
        Stack<int> moveHistory = new Stack<int>();
        public void RealizeMove(BitMove bm)
        {
            // check move validity...
            int[] moves = new int[200];
            int count = moveGenerator.GetMoves(Board, moves, 0, MoveGenerationMode.All);
            int compatible = 0;
            for (int i = 0; i < count; ++i)
            {
                BitMove fromGen = BitMove.FromRaw(moves[i], Board);
                if (bm.Equals(fromGen))
                {
                    compatible = moves[i];
                    break;
                }
            }
            if (compatible == 0)
            {
                throw new Exception("Invalid move:" + bm.ToString());
            }
            if (!moveGenerator.IsMoveLegal(Board, compatible))
            {
                throw new Exception("Invalid move:" + bm.ToString());
            }
            moveHistory.Push(compatible);
            Board.DoMove(compatible);
            if (moveGenerator.InCheck(Board, Flip(Board.ToMove)))
            {
                Board.UndoMove(compatible);
                moveHistory.Pop();
                throw new Exception("Invalid move ( in check ):" + bm.ToString());
            }
        }
        public void Undo()
        {
            int move = moveHistory.Pop();
            Board.UndoMove(move);
        }
        public void SetBoard(string fen)
        {
            Board.SetBoard(fen);
        }
        public string SavePos()
        {
            return Board.SavePos();
        }
        IMoveGenerator moveGenerator;

        public IMoveGenerator MoveGenerator
        {
            get { return moveGenerator; }
        }

        static BitBoardDriver()
        {
            //BuildZobristKeyGen();
           
        }
        public BitBoardDriver(IBitBoard bitBoard,IMoveGenerator moveGenerator)
           
        {
            this.Board = bitBoard;
            this.moveGenerator = moveGenerator;
        }
        
        public Side ToMove 
        {
            get { return Board.ToMove; }
        }
        public static Side Flip(Side s)
        {
            return s == Side.White ? Side.Black : Side.White;
        }
        public ulong GetPawns(Side s)
        {
            return Board.GetPawns(s);
        }
        public ulong GetKnights(Side s)
        {
            return Board.GetKnights(s);
        }
        public ulong GetBishops(Side s)
        {
            return Board.GetBishops(s);
        }
        public ulong GetRooks(Side s)
        {
            return Board.GetRooks(s);
        }
        public ulong GetQueens(Side s)
        {
            return Board.GetQueens(s);
        }
        public ulong GetKing(Side s)
        {
            return Board.GetKing(s);
        }
    }
}
